package com.zj.utils.internet;

import com.google.gson.Gson;

import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.Map;

import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
 * Rx网络请求
 *
 * @author jiang zhu on 2019/10/2
 */
public class RxAndroidUtils {

    private static RxAndroidUtils rxAndroidUtils;
    private Gson gson;

    private RxAndroidUtils() {
        gson = new Gson();
    }


    public static synchronized RxAndroidUtils getInstance() {
        if (rxAndroidUtils == null) {
            synchronized (RxAndroidUtils.class) {
                if (rxAndroidUtils == null) {
                    rxAndroidUtils = new RxAndroidUtils();
                }
            }
        }
        return rxAndroidUtils;
    }

    /**
     * 执行有参Get网络请求  返回指定类型
     *
     * @param url    网址
     * @param type   返回类型
     * @param params 传的参数
     * @param <T>    指定类型
     * @return 。
     */
    public synchronized <T> Observable<T> getRxData(String url, final Class<T> type, final Map<String, String> params) {
        if (params != null && !params.isEmpty()) {
            StringBuilder urlBuilder = new StringBuilder(url);
            for (Map.Entry<String, String> entry : params.entrySet()) {
                urlBuilder.append(entry.getKey()).append("=").append(entry.getKey()).append("&");
            }
            urlBuilder.substring(0, urlBuilder.length() - 1);
            url = urlBuilder.toString();
        }
        final String finalUrl = url;
        return Observable.create(emitter -> {
            if (!emitter.isDisposed()) {
                NetOkHttpUtils.getInstance().getData(finalUrl, new Callback() {
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {
                        emitter.onError(e);
                    }

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) {
                        observableEmitterOnNext(emitter, response, type);
                    }
                });
            }
        });
    }


    /**
     * 执行无参Get网络请求  返回指定类型
     *
     * @param url  网址
     * @param type 返回类型
     * @param <T>  指定类型
     * @return .
     */
    public synchronized <T> Observable<T> getRxData(final String url, final Class<T> type) {
        return Observable.create(emitter -> {
            if (!emitter.isDisposed()) {
                NetOkHttpUtils.getInstance().getData(url, new Callback() {
                    @Override
                    public void onFailure(@NotNull Call call, @NotNull IOException e) {
                        emitter.onError(e);
                    }

                    @Override
                    public void onResponse(@NotNull Call call, @NotNull Response response) {
                        observableEmitterOnNext(emitter, response, type);
                    }
                });
            }
        });
    }

    /**
     * 执行无参Post网络请求  返回指定类型
     *
     * @param url    网址
     * @param type   返回类型
     * @param params 传的参数
     * @param <T>    指定类型
     * @return 。
     */
    public synchronized <T> Observable<T> postRxData(final String url, final Class<T> type, Map<String, String> params) {
        String json = "";
        if (params != null && !params.isEmpty()) {
            json = gson.toJson(params);
        }
        final String finalJson = json;
        return Observable.create(new ObservableOnSubscribe<T>() {
            @Override
            public void subscribe(final ObservableEmitter<T> emitter) throws Exception {
                if (!emitter.isDisposed()) {
                    NetOkHttpUtils.getInstance().postData(url, finalJson, new Callback() {
                        @Override
                        public void onFailure(@NotNull Call call, @NotNull IOException e) {
                            emitter.onError(e);
                        }

                        @Override
                        public void onResponse(@NotNull Call call, @NotNull Response response) {
                            observableEmitterOnNext(emitter, response, type);
                        }
                    });
                }
            }
        });
    }


    /**
     * 执行无参Post网络请求  返回指定类型
     *
     * @param url  网址
     * @param type 返回类型
     * @param <T>  指定类型
     * @return .
     */
    public synchronized <T> Observable<T> postRxData(final String url, final Class<T> type) {
        return Observable.create(new ObservableOnSubscribe<T>() {
            @Override
            public void subscribe(final ObservableEmitter<T> emitter) throws Exception {
                if (!emitter.isDisposed()) {
                    NetOkHttpUtils.getInstance().postData(url, new Callback() {
                        @Override
                        public void onFailure(@NotNull Call call, @NotNull IOException e) {
                            emitter.onError(e);
                        }

                        @Override
                        public void onResponse(@NotNull Call call, @NotNull Response response) {
                            observableEmitterOnNext(emitter, response, type);
                        }
                    });
                }
            }
        });
    }

    /**
     * 根据传入的类型进行值得传递
     *
     * @param emitter  /
     * @param response 结果
     * @param type     类型
     * @param <T>      。
     */
    private <T> void observableEmitterOnNext(ObservableEmitter<T> emitter, Response response, Class<T> type) {
        String data = NetOkHttpUtils.getNetData(response);
        T entity = gson.fromJson(data, type);
        emitter.onNext(entity);
        emitter.onComplete();
    }


}
